#ifndef _SOCKET_H_XWW_20070808__
#define _SOCKET_H_XWW_20070808__
/* sock.h : socket */

#ifdef __cplusplus
extern "C" {
#endif


#ifdef _MSC_VER
	#include <winsock2.h>
	#pragma comment(lib, "ws2_32.lib")

	#define sock_errno WSAGetLastError()
	typedef unsigned int in_addr_t;
	typedef int socklen_t;
	#define SHUT_WR SD_SEND
	#define SHUT_RD SD_RECEIVE
	#define SHUT_RDWR SD_BOTH

	#define	EWOULDBLOCK	WSAEWOULDBLOCK	/* Operation would block */
	#define EINPROGRESS WSAEINPROGRESS


#elif __GNUC__

	#include <sys/ioctl.h>
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <arpa/inet.h>
	#include <errno.h>
	#include <unistd.h>
	#include <fcntl.h>
	#include <netdb.h>

	#ifndef ADDR_ANY
		#define ADDR_ANY                INADDR_ANY
	#endif


	#ifndef SOCKET
		#define SOCKET int
		#define INVALID_SOCKET -1
		#define SOCKET_ERROR -1
	#endif

	#ifndef NO_ERROR
		#define NO_ERROR 0
	#endif
	#ifndef closesocket
		#define closesocket close
	#endif
	#ifndef ioctlsocket
		#define ioctlsocket ioctl
	#endif
	#ifndef sock_errno
		#define sock_errno errno
	#endif
	
	#define SD_SEND SHUT_WR 
	#define SD_RECEIVE SHUT_RD 
	#define SD_BOTH SHUT_RDWR 

	#ifndef FD_READ
		#define FD_READ_BIT      0
		#define FD_READ          (1 << FD_READ_BIT)
		#define FD_WRITE_BIT     1
		#define FD_WRITE         (1 << FD_WRITE_BIT)
		#define FD_OOB_BIT       2
		#define FD_OOB           (1 << FD_OOB_BIT)
		#define FD_ACCEPT_BIT    3
		#define FD_ACCEPT        (1 << FD_ACCEPT_BIT)
		#define FD_CONNECT_BIT   4
		#define FD_CONNECT       (1 << FD_CONNECT_BIT)
		#define FD_CLOSE_BIT     5
		#define FD_CLOSE         (1 << FD_CLOSE_BIT)
	#endif

#else
	#error nonsupport
#endif

typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
typedef struct in_addr in_addr;

/**like inet_addr
 *@cp: "www.sina.com.cn" or "200.200.0.1"
 *@return: net order ip
 */
in_addr_t inet_addr_ex(const char* cp);

/* socket option */
int sock_setnblock(SOCKET fd, int act) ;
int sock_setndelay(SOCKET fd, int act) ;
int sock_setlinger(SOCKET fd, u_short l_onoff, u_short l_linger);
int sock_setkeepalive(SOCKET fd, int act) ;

/**
 * 
 */
#define sock_create  socket

int sock_create_nb(int domain, int type, int protocol);

#define sock_close(s)  do{ \
	closesocket(s); \
	s = INVALID_SOCKET; \
}while(0)

#define sock_accept  accept
#define sock_connect connect

/**
 * socket reset
 * @param fd
 * 
 * @return int 0:ok, -1:error
 */
#define sock_reset(s)  do {\
	sock_setlinger(s); \
	sock_close(s); \
	s = INVALID_SOCKET; \
}while(0)

#define sock_read  recv
#define sock_write send


#ifdef __cplusplus
}
#endif 
#endif //_SOCKET_H_XWW_20070808__

